home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c-part2 / 12765 < prev    next >
Encoding:
Text File  |  1996-08-05  |  4.3 KB  |  162 lines

  1. Newsgroups: comp.lang.c
  2. Path: news.Stanford.EDU!microunity!toms
  3. From: toms@MicroUnity.com (Tom Sanders)
  4. Subject: Re: How can I use huge || very small number?
  5. Message-ID: <Dp8y2E.5EK@microunity.com>
  6. Sender: usenet@microunity.com (news id)
  7. Organization: MicroUnity Systems Engineering, Inc.
  8. References: <315681F3.314D@blue.nowcom.co.kr> <4joh0l$jch@news.acns.nwu.edu> <4joijj$m0h@news.fsu.edu>
  9. Date: Tue, 2 Apr 1996 18:01:26 GMT
  10.  
  11. In article <4joijj$m0h@news.fsu.edu>, lloyd@upsilon.cs.fsu.edu (Justin C Lloyd) writes:
  12. |> On 1 Apr 1996 12:08:53 GMT, Usman Muzaffar (muzaffar@casbah.acns.nwu.edu)
  13. |> wrote:
  14. |> ** In article <315681F3.314D@blue.nowcom.co.kr>,
  15. |> ** whoever  <whatever@blue.nowcom.co.kr> wrote:
  16. |> ** >may be it is FAQ but...
  17. |> ** >how can I compute 10000! or 0.12345......
  18. |> 
  19. |> ** 10000! is a very, very big number.
  20. |> ** I'm not sure it's even representable by standard IEEE fp notation.
  21. |> ** Any have that formula? 2*pi*e something or another.
  22. |> 
  23. |> 
  24. |> I'm sorry that I don't remember the location (possibly sunsite.unc.edu?),
  25. |> but there was a collection of C snippets/programs that contained a program
  26. |> that "calculated" huge factorials by using strings.  I don't recall the
  27. |> algorithm, it was quite complicated.  Anyone else know what I'm referring
  28. |> to?
  29. |> 
  30. |> JcL
  31. |> --
  32.  
  33. The snippet collection is quite useful (over 500 utilities).  I don't 
  34. remember where I got it, but here is the C program for computing big
  35. factorials.
  36.  
  37. Tom Sanders
  38.  
  39. /*
  40. **  bigfac.c -- put into the public domain by Carl Declerck
  41. */
  42.  
  43. #include <stdio.h>
  44. #include <stdlib.h>
  45. #include <string.h>
  46.  
  47. #define BUFFLEN 8192
  48. #define BUFFER ((char *) malloc(BUFFLEN))
  49.  
  50. int  main (void);
  51. void multiply (char *, char *, char *);
  52. void zero_buffer (char *);
  53. void minus_one (char *);
  54. int  isnull (char *);
  55. void factorial (char *);
  56.  
  57. main (void)
  58. {
  59.       char *g = BUFFER;
  60.  
  61.       printf ("Enter a number: ");
  62.       scanf ("%s", g);
  63.       printf ("Factorial of %s is: ", g);
  64.       factorial (g);
  65.       printf ("%s\n", g);
  66.       free (g);
  67.       return 0;
  68. }
  69.  
  70. void multiply (char *g1, char *g2, char *g3)
  71. {
  72.       int gp1, gp2, cumpos, respos, mod, div;
  73.       int cmod, cdiv, resoff, wdig1, wdig2, base;
  74.  
  75.       zero_buffer (g3);
  76.       for (gp2 = strlen(g2) - 1; gp2 >= 0; gp2--)
  77.       {
  78.             wdig2 = *(g2 + gp2) - 48;
  79.             resoff = strlen(g2) - gp2 - 1;
  80.             respos = BUFFLEN - resoff - 2;
  81.             for (gp1 = strlen(g1) - 1; gp1 >= 0; gp1--)
  82.             {
  83.                   wdig1 = *(g1 + gp1) - 48;
  84.                   mod = (wdig1 * wdig2) % 10;
  85.                   div = (wdig1 * wdig2) / 10;
  86.                   base = *(g3 + respos) - 48;
  87.                   cmod = (base + mod) % 10;
  88.                   cdiv = (base + mod) / 10 + div;
  89.                   *(g3 + respos) = (char)(cmod + 48);
  90.                   cumpos = --respos;
  91.                   while (cdiv > 0)
  92.                   {
  93.                         base = *(g3 + cumpos) - 48;
  94.                         *(g3 + cumpos--) = (char)((base + cdiv) % 10 + 48);
  95.                         cdiv = (base + cdiv) / 10;
  96.                   }
  97.             }
  98.       }
  99.       for (respos = 0; *(g3 + respos) == '0'; respos++)
  100.             ;
  101.       strcpy (g3, (char *) (g3 + respos));
  102.       if (*g3 == 0)
  103.             strcpy (g3, "0");
  104. }
  105.  
  106. void zero_buffer (char *buff)
  107. {
  108.       int cnt;
  109.  
  110.       for (cnt= 0; cnt < BUFFLEN; cnt++)
  111.             *(buff + cnt) = '0';
  112.       *(buff + BUFFLEN - 1) = 0;
  113. }
  114.  
  115. void minus_one (char *g)
  116. {
  117.       int p;
  118.       char digit;
  119.  
  120.       p = strlen(g) - 1;
  121.       digit = *(g + p);
  122.       while (digit == '0')
  123.       {
  124.             *(g + p--) = '9';
  125.             digit = *(g + p);
  126.       }
  127.       *(g + p) -= 1;
  128. }
  129.  
  130. int isnull (char *g)
  131. {
  132.       int p, ok = 1;
  133.  
  134.       for (p = 0; p < (int)(strlen(g)); p++)
  135.             if (*(g + p) != '0')
  136.                   ok = 0;
  137.       return (ok);
  138. }
  139.  
  140. void factorial (char *g)
  141. {
  142.       char *h1 = BUFFER, *h2 = BUFFER;
  143.  
  144.       strcpy (h1, "1");
  145.       while (!isnull(g))
  146.       {
  147.             multiply (h1, g, h2);
  148.             strcpy (h1, h2);
  149.             minus_one (g);
  150.       }
  151.       strcpy (g, h1);
  152.       free (h1);
  153.       free (h2);
  154. }
  155.  
  156. /*
  157. **  The principal function is multiply(), it 'multiplies' two
  158. **  character-strings of arbitrary length and puts the result
  159. **  into a third.  8192 bytes is enough for 1000!, beyond that
  160. **  the buffer-size may need to be incremented.
  161. */
  162.